home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Presentations / Presentations ’92 / PatchWorks Kit / <PatchWorks++> / Patch.h < prev    next >
Text File  |  1992-05-19  |  5KB  |  197 lines

  1. /*
  2.     Patch.h
  3.     
  4.     Macros for patching traps and vectors.
  5.     
  6.     by Mouse Herrell & Patrick Beard.
  7.     
  8.     © 1991 Berkeley Systems Inc.
  9. */
  10.  
  11. #pragma once
  12.  
  13. #ifndef __PATCH__
  14. #define __PATCH__
  15.  
  16. #ifndef __QUICKDRAW__
  17. #include <QuickDraw.h>
  18. #endif
  19. #ifndef __OSUTILS__
  20. #include <OSUtils.h>
  21. #endif
  22. #ifndef __STDDEF__
  23. #include <stddef.h>
  24. #endif
  25.  
  26. // Macros & Inline glue to make patching easier.
  27.  
  28. #define GetTrapType(x)        (((x) & 0x800) != 0)
  29. #define InterruptMask(x)    ((x) << 8)
  30. #define    cSupervisorState    0x2000
  31.  
  32. #pragma parameter __D0 GetA4
  33. void* GetA4(void) = { 0x200c }; 
  34.  
  35. #pragma parameter __D0 SetA4(__D0)
  36. void* SetA4(void* newA4) = { 0xc18c };
  37.  
  38. #pragma parameter __D0 GetA5
  39. void* GetA5(void) = { 0x200d };
  40.  
  41. #pragma parameter __D0 GetA0
  42. void* GetA0(void) = { 0x2008 };
  43.  
  44. #pragma parameter __D0 GetSR
  45. short GetSR(void) = { 0x40c0 };
  46.  
  47. #pragma parameter __D0 SetSR(__D1)
  48. short SetSR(short) = { 0x40c0, 0x46c1 };
  49.  
  50. // tests and sets indivisibly (to avoid race conditions) using BSET.B #0
  51. #pragma parameter __D0 SetFlag(__A0)
  52. Boolean SetFlag(Boolean*) = { 0x08d0, 0x0000, 0x56c0 };
  53.  
  54. // types & constants.
  55.  
  56. enum PatchError {
  57.     eAbstractErr = 128,                            // An abstract method was called.
  58.     eBuriedPatchErr,                            // The patch removal failed because the vector has changed.
  59.     eEndPatchErrors
  60. };
  61.  
  62. typedef enum PatchError PatchError;
  63.  
  64. enum {
  65.     ePatchOff = 0,
  66.     ePatchOn
  67. };
  68.  
  69. typedef char PatchState;
  70.  
  71. // universal pointer to function.
  72.  
  73. typedef void* PatchProcPtr;
  74. typedef PatchProcPtr *PatchVectorPtr;            // pointer to a PatchProcPtr.
  75.  
  76. // stub of code that is allocated for every patch.
  77.  
  78. class Patch;
  79.  
  80. struct PatchStub {
  81.     short itsJsrJmp;
  82.     PatchProcPtr itsAgent;
  83.     Patch* itsPatch;
  84. };
  85.  
  86. typedef struct PatchStub PatchStub;
  87.  
  88. // patch class.
  89.  
  90. class Patch {
  91. protected:
  92.     Patch();                                    // constructor protected to prevent direct use.
  93.  
  94. public:
  95.     virtual ~Patch();                            // destruction is allowed.            
  96.  
  97.     void Install(void);                            // install the patch. delete to remove.
  98.     static void RemoveAll(void);                // remove all installed patches.
  99.     
  100.     void Enable(void);                            // enable the patch.
  101.     void Disable(void);                            // disable the patch.
  102.     PatchState Switch(PatchState state);        // get & set state.
  103.     
  104.     void* operator new(size_t n);                // memory allocator.
  105.     void operator delete(void* p);                // memory deallocator.
  106.  
  107. protected:
  108.     virtual PatchProcPtr GetAgent(void);        // returns pointer to agent code.
  109.     virtual    PatchProcPtr Get(void);                // retrieve the old address.
  110.     virtual void Set(PatchProcPtr proc);        // set the new address.
  111.  
  112. protected:
  113. #ifndef THINK_C
  114.     short itsClassId;                            // padding for universal glue.
  115. #endif
  116.     static Patch* theirList;                    // list of all installed patches.
  117.     Patch* itsNext;                                // next patch after this one.
  118.     
  119.     PatchProcPtr itsBehavior;                    // routine to call when patch hit.
  120.     PatchProcPtr itsOld;                        // old routine to call.
  121.     PatchStub* itsStub;                            // the universal glue code.
  122.     
  123.     void* itsGlobals;                            // pointer to globals.
  124.     Boolean itsInstalled;                        // if patch was ever installed.
  125.     PatchState itsState;                        // state of patch (enabled/disabled).
  126. };
  127.  
  128. class TrapPatch : public Patch {
  129. public:
  130.     void InitTrapPatch(PatchProcPtr proc, short trap);
  131.  
  132. protected:
  133.     virtual    PatchProcPtr Get(void);
  134.     virtual    void Set(PatchProcPtr proc);
  135.     
  136. protected:
  137.     short itsTrap;
  138. };
  139.  
  140. class VectorPatch : public Patch {
  141. public:
  142.     void InitVectorPatch(PatchProcPtr proc, PatchVectorPtr vector);
  143.  
  144. protected:
  145.     virtual    PatchProcPtr Get(void);
  146.     virtual    void Set(PatchProcPtr proc);
  147.     
  148. private:
  149.     PatchVectorPtr itsVector;
  150. };
  151.  
  152. // structure that represents the stack frame when the patch is given control.
  153.  
  154. struct PatchFrame {
  155.     Patch* patch;                    // pointer to current patch object.
  156.     void* offset;                    // magic address to adjust stack for tail patching.
  157.     long rd0;                        // caller's d0-d2/a0-a1 which might contain
  158.     long rd1;                        // parameters which patch can change.
  159.     long rd2;
  160.     void* ra0;
  161.     void* ra1;
  162.     void* ra4;                        // caller's a4 & a5 in case we use a4 globals.
  163.     void* ra5;
  164.     void* link;                        // link to previous stack frame. 28(sp)
  165.     void* old;                        // old address that will be returned to.
  166.     void* caller;                    // caller's address. 36(sp)
  167.     char parameters[1];                // array of parameters (if any)
  168. };
  169.  
  170. typedef struct PatchFrame PatchFrame;
  171.  
  172. struct ExceptionPatchFrame {
  173.     Patch*    patch;                    // pointer to current patch object.
  174.     void*    offset;                    // magic address to adjust stack for tail patching.
  175.     long    rd0;                    // caller's d0-d2/a0-a1 which might contain
  176.     long    rd1;                    // parameters which patch can change.
  177.     long    rd2;
  178.     void*    ra0;
  179.     void*    ra1;
  180.     void*    ra4;                    // caller's a4 & a5 in case we use a4 globals.
  181.     void*    ra5;
  182.     void*    link;                    // link to previous stack frame.
  183.     void*    old;                    // old address that will be returned to.
  184.     short    status;                    // value of status register.
  185.     void*    caller;                    // callers's address.
  186.     char    parameters[1];            // array of parameters (if any)
  187. };
  188.  
  189. typedef struct ExceptionPatchFrame ExceptionPatchFrame;
  190.  
  191. void CallOS(PatchFrame* frame);
  192. void VException(ExceptionPatchFrame frame);
  193. void PatchExceptions(void);
  194. void RestoreExceptions(void);
  195.  
  196. #endif
  197.